package net.stogi.common.gwt.dispatch.server.core.impl;

import net.stogi.common.gwt.dispatch.server.core.ActionHandler;
import net.stogi.common.gwt.dispatch.server.core.ActionHandlerRegistry;
import net.stogi.common.gwt.dispatch.server.core.Dispatch;
import net.stogi.common.gwt.dispatch.shared.core.Action;
import net.stogi.common.gwt.dispatch.shared.core.Result;
import net.stogi.common.gwt.dispatch.shared.exception.ActionException;
import net.stogi.common.gwt.dispatch.shared.exception.UnsupportedActionException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DispatchImpl<A extends Action<R>, R extends Result> implements Dispatch<A, R> {

	private static final Logger log = LoggerFactory.getLogger(DispatchImpl.class);

	private ActionHandlerRegistry<A, R> handlerRegistry;

	public DispatchImpl(ActionHandlerRegistry<A, R> handlerRegistry) {
		this.handlerRegistry = handlerRegistry;
	}

	public R execute(A action) throws ActionException {
		ActionHandler<A, R> handler = handlerRegistry.findHandler(action);

		if (handler == null) {
			log.warn("Unsupported action class: [ action.class = '{}']", action.getClass());
			throw new UnsupportedActionException(action);
		}

		try {
			R result = handler.execute(action);
			return result;
		}
		catch (ActionException e) {
			log.warn("Exception was thrown: [ e.message = '{}' ]", e.getMessage());
			throw e;
		}
	}
}
